Thao tác DOM chuyên sâu và xử lý sự kiện
← Quay lại trang chínhSau khi truy cập được phần tử DOM, chúng ta cần biết cách thay đổi nội dung của chúng để tạo ra trang web động và tương tác.
Mục đích: Cập nhật nội dung text an toàn, tự động escape HTML tags
Sử dụng khi: Hiển thị dữ liệu người dùng, đếm số lượng, thông báo đơn giản
// Hiển thị tên người dùng
const welcome = document.getElementById('welcome');
welcome.textContent = "Xin chào " + username + "!";
// Cập nhật số lượng
const counter = document.getElementById('counter');
counter.textContent = count + " sản phẩm";
Mục đích: Cập nhật nội dung có định dạng HTML, tạo cấu trúc phức tạp
Sử dụng khi: Tạo danh sách, bài viết, card sản phẩm có định dạng
// Tạo card sản phẩm
const productCard = document.getElementById('product');
productCard.innerHTML = `
<img src="${product.image}" alt="${product.name}">
<h3>${product.name}</h3>
<p class="price">${product.price} VNĐ</p>
<button>Mua ngay</button>
`;
Để tạo nội dung động, chúng ta cần biết cách tạo mới và chèn các phần tử HTML vào trang.
Mục đích: Tạo phần tử HTML hoàn toàn mới trong bộ nhớ
Sử dụng khi: Cần tạo nội dung động, thông báo, popup, danh sách item
// Tạo thông báo mới
const notification = document.createElement('div');
notification.className = 'alert alert-success';
notification.textContent = 'Đã lưu thành công!';
// Tạo item trong todo list
const todoItem = document.createElement('li');
todoItem.innerHTML = `
<span>${taskText}</span>
<button onclick="deleteTask()">Xóa</button>
`;
Mục đích: Chèn phần tử mới vào cuối danh sách con
Sử dụng khi: Thêm tin nhắn mới, comment, sản phẩm vào danh sách
// Thêm item vào danh sách
const list = document.getElementById('todoList');
const newItem = document.createElement('li');
newItem.textContent = 'Task mới';
list.appendChild(newItem); // Thêm vào cuối
// insertBefore() - Thêm vào vị trí cụ thể
const firstItem = list.firstChild;
list.insertBefore(newItem, firstItem); // Thêm vào đầu
Container - các phần tử mới sẽ xuất hiện ở đây
// Hàm tạo và chèn phần tử (tương tự demo trên)
function createAndInsert() {
// 1. Lấy dữ liệu từ input
const content = document.getElementById('elementContent').value || `Element ${itemCounter}`;
const tag = document.getElementById('elementTag').value;
const method = document.getElementById('insertMethod').value;
const container = document.getElementById('insertContainer');
// 2. Tạo phần tử mới
const newElement = document.createElement(tag);
newElement.textContent = content;
// 3. Style cho phần tử
newElement.style.background = '#d4edda';
newElement.style.padding = '8px';
newElement.style.margin = '4px 0';
newElement.style.borderRadius = '5px';
newElement.style.border = '1px solid #c3e6cb';
// 4. Chèn theo phương thức được chọn
if (method === 'appendChild') {
container.appendChild(newElement); // Thêm vào cuối
} else if (method === 'prepend') {
container.insertBefore(newElement, container.firstChild); // Thêm vào đầu
} else if (method === 'before') {
container.parentNode.insertBefore(newElement, container); // Trước container
} else if (method === 'after') {
container.parentNode.insertBefore(newElement, container.nextSibling); // Sau container
}
// 5. Cập nhật kết quả và reset input
document.getElementById('insertResult').innerHTML =
`<strong>Đã tạo:</strong> <${tag}> với nội dung "${content}" bằng phương thức ${method}()`;
document.getElementById('elementContent').value = '';
itemCounter++;
}
// Hàm chèn HTML trực tiếp
function insertHTML() {
const content = document.getElementById('elementContent').value || 'HTML Content';
const container = document.getElementById('insertContainer');
// insertAdjacentHTML - chèn HTML string
const htmlContent = `<div style="background:#fff3cd; padding:8px; margin:4px 0; border-radius:5px;">
<strong>HTML:</strong> ${content}
</div>`;
container.insertAdjacentHTML('beforeend', htmlContent);
document.getElementById('insertResult').innerHTML =
`<strong>insertAdjacentHTML:</strong> Đã chèn HTML "${content}" trực tiếp`;
document.getElementById('elementContent').value = '';
}
// Hàm clone phần tử cuối
function cloneLastElement() {
const container = document.getElementById('insertContainer');
const elements = Array.from(container.children).filter(el => el.tagName !== 'P');
if (elements.length > 0) {
const lastElement = elements[elements.length - 1];
const cloned = lastElement.cloneNode(true);
cloned.style.background = '#f8d7da';
cloned.style.borderColor = '#f5c6cb';
cloned.textContent += ' (bản sao)';
container.appendChild(cloned);
document.getElementById('insertResult').innerHTML =
`<strong>cloneNode:</strong> Đã sao chép phần tử cuối cùng`;
} else {
document.getElementById('insertResult').textContent = 'Không có phần tử nào để sao chép!';
}
}
function clearContainer() {
const container = document.getElementById('insertContainer');
container.innerHTML = 'Container - các phần tử mới sẽ xuất hiện ở đây
';
itemCounter = 1;
document.getElementById('insertResult').innerHTML = 'Đã xóa: Tất cả phần tử trong container';
}
Quản lý DOM cũng bao gồm việc xóa những phần tử không còn cần thiết và thay thế nội dung cũ.
Mục đích: Xóa phần tử khỏi DOM một cách đơn giản
Sử dụng khi: Xóa thông báo, task completed, popup, modal
// Cách hiện đại (ES6+)
const element = document.getElementById('myElement');
element.remove(); // Tự xóa chính nó
// Cách cũ (vẫn hoạt động)
const parent = element.parentNode;
parent.removeChild(element);
Mục đích: Thay thế phần tử cũ bằng phần tử mới hoàn toàn
Sử dụng khi: Cập nhật nội dung phức tạp, thay đổi cấu trúc
// Tạo phần tử mới
const newElement = document.createElement('div');
newElement.textContent = 'Nội dung mới';
// Thay thế
const oldElement = document.getElementById('oldElement');
oldElement.replaceWith(newElement);
👆 Click vào item để chọn, sau đó sử dụng các nút bên dưới
let selectedItem = null;
let itemCounter = 4;
// Hàm chọn item (highlight)
function selectItem(element, id) {
// 1. Bỏ selection cũ
document.querySelectorAll('.deletable-item').forEach(item => {
item.style.border = '2px solid transparent';
item.style.background = '#d4edda';
});
// 2. Highlight item được chọn
element.style.border = '2px solid #667eea';
element.style.background = '#e3f2fd';
selectedItem = element;
// 3. Cập nhật thông báo
document.getElementById('deleteResult').innerHTML =
`<strong>Đã chọn:</strong> "${element.textContent}" - Có thể xóa hoặc thay thế`;
// Update HTML source if tab is active
if (document.getElementById('htmlTab').classList.contains('active')) {
refreshHTMLSource();
}
}
// Hàm xóa item được chọn
function deleteSelected() {
if (selectedItem) {
const text = selectedItem.textContent;
// Modern way: element tự xóa chính nó
selectedItem.remove();
selectedItem = null;
document.getElementById('deleteResult').innerHTML =
`<strong>remove():</strong> Đã xóa "${text}" - Phần tử tự xóa chính nó`;
// Update HTML source if tab is active
if (document.getElementById('htmlTab').classList.contains('active')) {
refreshHTMLSource();
}
} else {
document.getElementById('deleteResult').textContent = 'Vui lòng chọn một item trước khi xóa!';
}
}
// Hàm thay thế item được chọn
function replaceSelected() {
if (selectedItem) {
const newContent = document.getElementById('replaceContent').value || 'Nội dung mặc định';
const oldText = selectedItem.textContent;
// 1. Tạo phần tử mới
const newElement = document.createElement('div');
newElement.className = 'deletable-item';
newElement.textContent = newContent;
// 2. Style cho phần tử mới
newElement.style.background = '#d1ecf1';
newElement.style.padding = '10px';
newElement.style.margin = '5px 0';
newElement.style.borderRadius = '5px';
newElement.style.cursor = 'pointer';
newElement.style.border = '2px solid transparent';
// 3. Gắn event listener
newElement.onclick = function() { selectItem(this, itemCounter++); };
// 4. Thay thế element cũ bằng mới
selectedItem.replaceWith(newElement);
selectedItem = null;
document.getElementById('deleteResult').innerHTML =
`<strong>replaceWith():</strong> "${oldText}" → "${newContent}"`;
document.getElementById('replaceContent').value = '';
// Update HTML source if tab is active
if (document.getElementById('htmlTab').classList.contains('active')) {
refreshHTMLSource();
}
} else {
document.getElementById('deleteResult').textContent = 'Vui lòng chọn một item trước khi thay thế!';
}
}
// Hàm thêm item mới
function addNewItem() {
const container = document.getElementById('deleteContainer');
// 1. Tạo element mới
const newItem = document.createElement('div');
newItem.className = 'deletable-item';
newItem.textContent = `📄 Item ${itemCounter} - Click để chọn`;
// 2. Style
newItem.style.background = '#d4edda';
newItem.style.padding = '10px';
newItem.style.margin = '5px 0';
newItem.style.borderRadius = '5px';
newItem.style.cursor = 'pointer';
newItem.style.border = '2px solid transparent';
// 3. Event listener
newItem.onclick = function() { selectItem(this, itemCounter); };
// 4. Thêm vào container
container.appendChild(newItem);
document.getElementById('deleteResult').innerHTML =
`<strong>createElement + appendChild:</strong> Đã thêm Item ${itemCounter}`;
itemCounter++;
// Update HTML source if tab is active
if (document.getElementById('htmlTab').classList.contains('active')) {
refreshHTMLSource();
}
}
function resetDeleteDemo() {
const container = document.getElementById('deleteContainer');
// Khôi phục HTML ban đầu
container.innerHTML = `
<div class="deletable-item" style="background:#d4edda; padding:10px; margin:5px 0; border-radius:5px; cursor:pointer; border:2px solid transparent;" onclick="selectItem(this, 1)">
📄 Item 1 - Click để chọn
</div>
<div class="deletable-item" style="background:#d4edda; padding:10px; margin:5px 0; border-radius:5px; cursor:pointer; border:2px solid transparent;" onclick="selectItem(this, 2)">
📄 Item 2 - Click để chọn
</div>
<div class="deletable-item" style="background:#d4edda; padding:10px; margin:5px 0; border-radius:5px; cursor:pointer; border:2px solid transparent;" onclick="selectItem(this, 3)">
📄 Item 3 - Click để chọn
</div>
`;
selectedItem = null;
itemCounter = 4;
document.getElementById('deleteResult').innerHTML = 'Reset: Đã khôi phục lại demo ban đầu';
// Update HTML source if tab is active
if (document.getElementById('htmlTab').classList.contains('active')) {
refreshHTMLSource();
}
}
Event (sự kiện) là các hành động xảy ra trên trang web như click chuột, nhập bàn phím, di chuyển chuột... JavaScript có thể "lắng nghe" và phản ứng với các sự kiện này.
// Cách 1: HTML attribute (không khuyến khích)
<button onclick="alert('Clicked!')">Click me</button>
// Cách 2: addEventListener (khuyến khích)
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log('Button được click!');
});
// Event với tham số
button.addEventListener('click', function(event) {
console.log('Click tại vị trí:', event.clientX, event.clientY);
event.preventDefault(); // Ngăn hành động mặc định
});